package com.eta.common.exception;

import com.eta.common.constant.ResultCodeEnum;
import com.eta.common.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author 星河一叶Ck
 * @date 2025/9/6
 * @description 全局异常处理类
 */

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    // -------------------------- 自定义业务异常--------------------------
    /**
     * 捕获自定义的 BusinessException（如“手机号已注册”“账号不存在”等业务异常）
     * 这类异常是我们主动抛出的，消息可直接返回给前端
     */
    @ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException e) {
        log.info("业务异常: {}", e.getMessage());
        return Result.fail(e.getErrorCode(), e.getMessage());
    }

    // -------------------------- 参数校验异常（如@NotBlank、@Pattern校验失败）--------------------------

    /**
     * 捕获参数校验异常（MethodArgumentNotValidException）
     * 对应 @Valid 注解校验DTO参数时的失败场景（如登录账号为空、密码格式错误）
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        String errorMsg = fieldError.getField() + ": " + fieldError.getDefaultMessage();

        log.warn("参数校验失败: {}", errorMsg);
        return Result.fail(ResultCodeEnum.PARAM_ERROR, errorMsg);
    }

    // -------------------------- 数据库异常（如唯一键冲突、字段长度超限）--------------------------
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public Result handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
        String errorMsg = e.getMessage();
        log.warn("数据库异常: {}", errorMsg);

        // 解析异常消息，返回更友好的提示（避免前端看到SQL层面的错误）
        if (errorMsg.contains("uk_sys_user_account")) { // 匹配账号唯一索性
            return Result.fail(ResultCodeEnum.USER_ACCOUNT_EXIST);
        } else if(errorMsg.contains("uk_sys_user_phone")) { // 匹配手机唯一索性
            return Result.fail(ResultCodeEnum.USER_PHONE_EXIST);
        } else if (errorMsg.contains("uk_sys_user_email")) { // 匹配邮箱唯一索引
            return Result.fail(ResultCodeEnum.USER_EMAIL_EXIST);
        } else {
            // 其他数据库异常，返回通用提示（不暴露具体SQL错误）
            return Result.fail(ResultCodeEnum.DB_ERROR);
        }
    }

    // -------------------------- 通用异常--------------------------
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleException(Exception e) {
        log.error("系统异常: ", e);
        return Result.fail(ResultCodeEnum.SYSTEM_ERROR);
    }
}
